//
//  ViewController.m
//  解析（ XML）
//
//  Created by apple on 15/9/1.
//  Copyright (c) 2015年 戴维营. All rights reserved.
//

#import "ViewController.h"
#import "Book.h"

//解析器
#import <libxml/parser.h>
//----------------------------------------------

#import <libxml/xpath.h>

@interface ViewController () <NSXMLParserDelegate>
{
    NSString *_filePath;
    
    NSMutableArray *_array;
    
    NSMutableString *_str;


}


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
//    XML 解析方法；
    
//    XML解析的方式有SAX和DOM两种方式，在iOS中提供了c接口的libxml2（ DOM ）和Objective-C ( SAX )的NSXMLParser两种方式；
    
    
//    1、libxml2

//    libxml2 是GNU的一个c语言的跨平台开源xml解析库，支持DOM和SAX方式解析，并且支持通过XPath方式遍历DOM树查询数据。libxml2支持HTML解析。
    
    
//     使用libxml2需要先引入libxml2.dylib并且设置好头文件的搜索路径。
    
    
//    xml文件路径；
    _filePath = @"/Users/apple/Desktop/下载下来的类文件/BookList.xml";
#if 0
//    解析xml文件
    xmlDocPtr doc = xmlParseFile([_filePath UTF8String]);//1⃣️
#endif
    
#if 0
//    读取xml文件
    NSString *xmlStr = [NSString stringWithContentsOfFile:_filePath encoding:NSUTF8StringEncoding error:nil];
//    解析，但不要直接的使用NSString的length的方法；
    xmlDocPtr doc = xmlParseMemory([xmlStr UTF8String], (int)[xmlStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
    
    xmlNodePtr curNode = xmlDocGetRootElement(doc);
    
    if (xmlStrcmp(curNode->name, (const xmlChar *)"Student"))
    {
        NSLog(@"根节点不是student");
        return;
    }
    
    curNode = curNode->children;
    while (curNode != NULL)
    {
        if (!xmlStrcmp(curNode->name, (const xmlChar *)"BookList"))
        {
            xmlNodePtr book = curNode->children;
            while (book != NULL)
            {
                if (!xmlStrcmp(book->name, (const xmlChar *)"Book"))
                {
                    NSLog(@"bookName:%s",book->name);
                    NSLog(@"bookId:%s",xmlGetProp(book, (const xmlChar *)"id"));
                    xmlChar *content = xmlNodeListGetRawString(doc, book->children, 1);
                    NSLog(@"content:%@",[NSString stringWithCString:(const char *)content encoding:NSUTF8StringEncoding]);
                    xmlFree(content);
                }
                
                book = book->next;
            }
        }
        
        curNode = curNode->next;
    }

// xPath
    
//    遍历DOM树的方式比较复杂，可以用来获取资源和修改XML,但是不方便，尤其是在文档树较大的情况下。常通过XPath查询特定的数据内容。
    
    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
    xmlXPathObjectPtr result = xmlXPathEval((const xmlChar *)"BookList/Book[1]",xpathCtx );
    xmlNodePtr = curNode2 = result->nodesetval->nodeTab[0];
    xmlChar *content = xmlNodeListGetRawString(doc, curNode->children, 1);
    
    NSLog(@"name---->%@",[NSString stringWithCString:(const char *)content encoding:NSUTF8StringEncoding]);
    xmlXPathFreeContext(xpathCtx);
    

    xmlFreeDoc(doc);
    
#endif
    
//    NSXMLParser:是一个objective-c 的类，只支持SAX方式解析XML，通过NSXMLParserDelegate的代理方法返回数据和解析状态，是一种事件驱动的解析方式；
    
 
    
    
// 1、   创建解析器对象；
    
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL fileURLWithPath:_filePath]];
    
//  2、   设置代理对象；
    
    parser.delegate = self;
    
//    开始解析；
    
    [parser parse];
    
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)parserDidStartDocument:(NSXMLParser *)parser
{
//    NSLog(@"开始读取文档");
//    NSLog(@"_array:%@",_array);
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//    NSLog(@"开始读取元素");
    if ([elementName isEqualToString:@"Book"])
    {
        if (!_array)
        {
            _array = [NSMutableArray array];
        }
        Book *book = [Book new];
        book.bookId = [attributeDict[@"id"]integerValue];

        
//      NSInteger bId = [attributeDict[@"id"]];
//      book.bookId = bId;
        
        [_array addObject:book];
        
        
//        NSLog(@"%@",_array);
        
        
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//    NSLog(@"读取文件内容");
    if (![string containsString:@"\n"])
    {
        if (!_str)
        {
            _str = [NSMutableString string];
        }
//        Book *book = [Book new];
//        book.bookName = string;
        [_str appendString:string];
        
        
//        NSLog(@"%@",_str);
        
        
    }
}

//  在结束读取元素的时候给内容赋值，以保证内容的完整性；


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//    NSLog(@"结束读取元素");
//    NSLog(@"%@",elementName);
    if ([elementName isEqualToString:@"Book"])
    {
//-----------------------------------------------------?
        Book *tempBook = [_array lastObject];
        tempBook.bookName = _str;
//----------------------------------------------------------------
    }
    
    _str = nil;
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//    NSLog(@"结束读取文档");
    for (Book *book in _array)
    {
        NSLog(@"bookID:%ld",book.bookId);
        NSLog(@"bookName:%@",book.bookName);
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
